/*     */ package com.zimbra.cs.service.mail;
/*     */ 
/*     */ import com.zimbra.client.ZContact;
/*     */ import com.zimbra.client.ZFolder;
/*     */ import com.zimbra.client.ZMailbox;
/*     */ import com.zimbra.client.ZMailbox.Options;
/*     */ import com.zimbra.client.ZMailbox.ZAttachmentInfo;
/*     */ import com.zimbra.client.ZMountpoint;
/*     */ import com.zimbra.common.account.Key.AccountBy;
/*     */ import com.zimbra.common.auth.ZAuthToken;
/*     */ import com.zimbra.common.mailbox.Color;
/*     */ import com.zimbra.common.mailbox.ContactConstants;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.soap.Element;
/*     */ import com.zimbra.common.soap.Element.XMLElement;
/*     */ import com.zimbra.common.soap.MailConstants;
/*     */ import com.zimbra.common.soap.SoapHttpTransport;
/*     */ import com.zimbra.common.soap.SoapProtocol;
/*     */ import com.zimbra.common.util.ByteUtil;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.Pair;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import com.zimbra.cs.account.Account;
/*     */ import com.zimbra.cs.account.AuthToken;
/*     */ import com.zimbra.cs.account.Provisioning;
/*     */ import com.zimbra.cs.mailbox.CalendarItem;
/*     */ import com.zimbra.cs.mailbox.Contact;
/*     */ import com.zimbra.cs.mailbox.Contact.Attachment;
/*     */ import com.zimbra.cs.mailbox.ContactGroup;
/*     */ import com.zimbra.cs.mailbox.ContactGroup.Member;
/*     */ import com.zimbra.cs.mailbox.Conversation;
/*     */ import com.zimbra.cs.mailbox.Document;
/*     */ import com.zimbra.cs.mailbox.Flag;
/*     */ import com.zimbra.cs.mailbox.Flag.FlagInfo;
/*     */ import com.zimbra.cs.mailbox.Folder;
/*     */ import com.zimbra.cs.mailbox.MailItem;
/*     */ import com.zimbra.cs.mailbox.MailItem.TargetConstraint;
/*     */ import com.zimbra.cs.mailbox.MailItem.Type;
/*     */ import com.zimbra.cs.mailbox.MailServiceException;
/*     */ import com.zimbra.cs.mailbox.Mailbox;
/*     */ import com.zimbra.cs.mailbox.Message;
/*     */ import com.zimbra.cs.mailbox.Mountpoint;
/*     */ import com.zimbra.cs.mailbox.OperationContext;
/*     */ import com.zimbra.cs.mailbox.calendar.Invite;
/*     */ import com.zimbra.cs.mailbox.calendar.ZOrganizer;
/*     */ import com.zimbra.cs.service.util.ItemId;
/*     */ import com.zimbra.cs.service.util.ItemIdFormatter;
/*     */ import com.zimbra.cs.service.util.SpamHandler;
/*     */ import com.zimbra.cs.service.util.SpamHandler.SpamReport;
/*     */ import com.zimbra.cs.store.StoreManager;
/*     */ import java.io.ByteArrayOutputStream;
/*     */ import java.io.IOException;
/*     */ import java.io.InputStream;
/*     */ import java.util.ArrayList;
/*     */ import java.util.Arrays;
/*     */ import java.util.HashMap;
/*     */ import java.util.Iterator;
/*     */ import java.util.List;
/*     */ import java.util.Map;
/*     */ import javax.mail.MessagingException;
/*     */ import javax.mail.internet.MimeMessage;
/*     */ import org.dom4j.QName;
/*     */ 
/*     */ public class ItemActionHelper
/*     */ {
/*     */   protected String mResult;
/*     */   protected List<String> mCreatedIds;
/*     */   protected SoapProtocol mResponseProtocol;
/*     */   protected Op mOperation;
/*     */   protected int[] itemIds;
/*     */   protected MailItem.Type type;
/*     */   protected boolean mFlagValue;
/*     */   protected MailItem.TargetConstraint mTargetConstraint;
/*     */   protected int mHopCount;
/*     */   protected String mTagName;
/*     */   protected Color mColor;
/*     */   protected String mName;
/*     */   protected ItemId mIidFolder;
/*     */   protected ItemId mIidRequestedFolder;
/*     */   protected String mFlags;
/*     */   protected String[] mTags;
/*     */   protected ItemIdFormatter mIdFormatter;
/*     */   protected Account mAuthenticatedAccount;
/*     */   private final OperationContext mOpCtxt;
/*     */   private final Mailbox mMailbox;
/*     */   
/*     */   public static ItemActionHelper TAG(OperationContext octxt, Mailbox mbox, SoapProtocol responseProto, List<Integer> ids, MailItem.Type type, String tagName, boolean flagValue, MailItem.TargetConstraint tcon) throws ServiceException
/*     */   {
/*  89 */     ItemActionHelper ia = new ItemActionHelper(octxt, mbox, responseProto, ids, Op.TAG, type, flagValue, tcon);
/*     */     
/*  91 */     ia.setTagName(tagName);
/*  92 */     ia.schedule();
/*  93 */     return ia;
/*     */   }
/*     */   
/*     */   public static ItemActionHelper FLAG(OperationContext octxt, Mailbox mbox, SoapProtocol responseProto, List<Integer> ids, MailItem.Type type, boolean flagValue, MailItem.TargetConstraint tcon) throws ServiceException
/*     */   {
/*  98 */     ItemActionHelper ia = new ItemActionHelper(octxt, mbox, responseProto, ids, Op.FLAG, type, flagValue, tcon);
/*  99 */     ia.schedule();
/* 100 */     return ia;
/*     */   }
/*     */   
/*     */   public static ItemActionHelper PRIORITY(OperationContext octxt, Mailbox mbox, SoapProtocol responseProto, List<Integer> ids, MailItem.Type type, boolean flagValue, MailItem.TargetConstraint tcon) throws ServiceException
/*     */   {
/* 105 */     ItemActionHelper ia = new ItemActionHelper(octxt, mbox, responseProto, ids, Op.PRIORITY, type, flagValue, tcon);
/* 106 */     ia.schedule();
/* 107 */     return ia;
/*     */   }
/*     */   
/*     */   public static ItemActionHelper READ(OperationContext octxt, Mailbox mbox, SoapProtocol responseProto, List<Integer> ids, MailItem.Type type, boolean flagValue, MailItem.TargetConstraint tcon) throws ServiceException
/*     */   {
/* 112 */     ItemActionHelper ia = new ItemActionHelper(octxt, mbox, responseProto, ids, Op.READ, type, flagValue, tcon);
/* 113 */     ia.schedule();
/* 114 */     return ia;
/*     */   }
/*     */   
/*     */   public static ItemActionHelper COLOR(OperationContext octxt, Mailbox mbox, SoapProtocol responseProto, List<Integer> ids, MailItem.Type type, MailItem.TargetConstraint tcon, Color color)
/*     */     throws ServiceException
/*     */   {
/* 120 */     ItemActionHelper ia = new ItemActionHelper(octxt, mbox, responseProto, ids, Op.COLOR, type, true, tcon);
/* 121 */     ia.setColor(color);
/* 122 */     ia.schedule();
/* 123 */     return ia;
/*     */   }
/*     */   
/*     */   public static ItemActionHelper HARD_DELETE(OperationContext octxt, Mailbox mbox, SoapProtocol responseProto, List<Integer> ids, MailItem.Type type, MailItem.TargetConstraint tcon) throws ServiceException
/*     */   {
/* 128 */     ItemActionHelper ia = new ItemActionHelper(octxt, mbox, responseProto, ids, Op.HARD_DELETE, type, true, tcon);
/* 129 */     ia.schedule();
/* 130 */     return ia;
/*     */   }
/*     */   
/*     */   public static ItemActionHelper RECOVER(OperationContext octxt, Mailbox mbox, SoapProtocol responseProto, List<Integer> ids, MailItem.Type type, MailItem.TargetConstraint tcon, ItemId iidFolder) throws ServiceException
/*     */   {
/* 135 */     ItemActionHelper ia = new ItemActionHelper(octxt, mbox, responseProto, ids, Op.RECOVER, type, true, tcon);
/* 136 */     ia.setIidFolder(iidFolder);
/* 137 */     ia.schedule();
/* 138 */     return ia;
/*     */   }
/*     */   
/*     */   public static ItemActionHelper DUMPSTER_DELETE(OperationContext octxt, Mailbox mbox, SoapProtocol responseProto, List<Integer> ids, MailItem.Type type, MailItem.TargetConstraint tcon) throws ServiceException
/*     */   {
/* 143 */     ItemActionHelper ia = new ItemActionHelper(octxt, mbox, responseProto, ids, Op.DUMPSTER_DELETE, type, true, tcon);
/* 144 */     ia.schedule();
/* 145 */     return ia;
/*     */   }
/*     */   
/*     */   public static ItemActionHelper MOVE(OperationContext octxt, Mailbox mbox, SoapProtocol responseProto, List<Integer> ids, MailItem.Type type, MailItem.TargetConstraint tcon, ItemId iidFolder) throws ServiceException
/*     */   {
/* 150 */     ItemActionHelper ia = new ItemActionHelper(octxt, mbox, responseProto, ids, Op.MOVE, type, true, tcon);
/* 151 */     ia.setIidFolder(iidFolder);
/* 152 */     ia.schedule();
/* 153 */     return ia;
/*     */   }
/*     */   
/*     */   public static ItemActionHelper COPY(OperationContext octxt, Mailbox mbox, SoapProtocol responseProto, List<Integer> ids, MailItem.Type type, MailItem.TargetConstraint tcon, ItemId iidFolder)
/*     */     throws ServiceException
/*     */   {
/* 159 */     ItemActionHelper ia = new ItemActionHelper(octxt, mbox, responseProto, ids, Op.COPY, type, true, tcon);
/* 160 */     ia.setIidFolder(iidFolder);
/* 161 */     ia.schedule();
/* 162 */     return ia;
/*     */   }
/*     */   
/*     */   public static ItemActionHelper SPAM(OperationContext octxt, Mailbox mbox, SoapProtocol responseProto, List<Integer> ids, MailItem.Type type, boolean flagValue, MailItem.TargetConstraint tcon, ItemId iidFolder)
/*     */     throws ServiceException
/*     */   {
/* 168 */     ItemActionHelper ia = new ItemActionHelper(octxt, mbox, responseProto, ids, Op.SPAM, type, flagValue, tcon);
/* 169 */     ia.setIidFolder(iidFolder);
/* 170 */     ia.schedule();
/* 171 */     return ia;
/*     */   }
/*     */   
/*     */   public static ItemActionHelper RENAME(OperationContext octxt, Mailbox mbox, SoapProtocol responseProto, List<Integer> ids, MailItem.Type type, MailItem.TargetConstraint tcon, String name, ItemId iidFolder)
/*     */     throws ServiceException
/*     */   {
/* 177 */     ItemActionHelper ia = new ItemActionHelper(octxt, mbox, responseProto, ids, Op.RENAME, type, true, tcon);
/* 178 */     ia.setName(name);
/* 179 */     ia.setIidFolder(iidFolder);
/* 180 */     ia.schedule();
/* 181 */     return ia;
/*     */   }
/*     */   
/*     */   public static ItemActionHelper UPDATE(OperationContext octxt, Mailbox mbox, SoapProtocol responseProto, List<Integer> ids, MailItem.Type type, MailItem.TargetConstraint tcon, String name, ItemId iidFolder, String flags, String[] tags, Color color)
/*     */     throws ServiceException
/*     */   {
/* 187 */     ItemActionHelper ia = new ItemActionHelper(octxt, mbox, responseProto, ids, Op.UPDATE, type, true, tcon);
/* 188 */     ia.setName(name);
/* 189 */     ia.setIidFolder(iidFolder);
/* 190 */     ia.setFlags(flags);
/* 191 */     ia.setTags(tags);
/* 192 */     ia.setColor(color);
/* 193 */     ia.schedule();
/* 194 */     return ia;
/*     */   }
/*     */   
/*     */   public static ItemActionHelper LOCK(OperationContext octxt, Mailbox mbox, SoapProtocol responseProto, List<Integer> ids, MailItem.Type type, MailItem.TargetConstraint tcon) throws ServiceException
/*     */   {
/* 199 */     ItemActionHelper ia = new ItemActionHelper(octxt, mbox, responseProto, ids, Op.LOCK, type, true, tcon);
/* 200 */     ia.schedule();
/* 201 */     return ia;
/*     */   }
/*     */   
/*     */   public static ItemActionHelper UNLOCK(OperationContext octxt, Mailbox mbox, SoapProtocol responseProto, List<Integer> ids, MailItem.Type type, MailItem.TargetConstraint tcon) throws ServiceException
/*     */   {
/* 206 */     ItemActionHelper ia = new ItemActionHelper(octxt, mbox, responseProto, ids, Op.UNLOCK, type, true, tcon);
/* 207 */     ia.schedule();
/* 208 */     return ia;
/*     */   }
/*     */   
/*     */   public static enum Op {
/* 212 */     TAG("tag"), 
/* 213 */     FLAG("flag"), 
/* 214 */     PRIORITY("priority"), 
/* 215 */     READ("read"), 
/* 216 */     COLOR("color"), 
/* 217 */     HARD_DELETE("delete"), 
/* 218 */     RECOVER("recover"), 
/* 219 */     DUMPSTER_DELETE("dumpsterdelete"), 
/* 220 */     MOVE("move"), 
/* 221 */     COPY("copy"), 
/* 222 */     SPAM("spam"), 
/* 223 */     RENAME("rename"), 
/* 224 */     UPDATE("update"), 
/* 225 */     LOCK("lock"), 
/* 226 */     UNLOCK("unlock");
/*     */     
/*     */     private final String name;
/*     */     
/*     */     private Op(String name) {
/* 231 */       this.name = name;
/*     */     }
/*     */     
/*     */     public String toString()
/*     */     {
/* 236 */       return this.name;
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public String toString()
/*     */   {
/* 273 */     StringBuilder toRet = new StringBuilder(super.toString());
/*     */     
/* 275 */     toRet.append(" Op=").append(this.mOperation.toString());
/* 276 */     toRet.append(" Type=").append(this.type);
/* 277 */     toRet.append(" FlagValue=").append(this.mFlagValue);
/* 278 */     if (this.mTargetConstraint != null) {
/* 279 */       toRet.append(" TargetConst=").append(this.mTargetConstraint.toString());
/*     */     }
/*     */     
/* 282 */     if (this.mOperation == Op.TAG) {
/* 283 */       toRet.append(" TagName=").append(this.mTagName);
/*     */     }
/*     */     
/* 286 */     if ((this.mOperation == Op.COLOR) || (this.mOperation == Op.UPDATE)) {
/* 287 */       toRet.append(" Color=").append(this.mColor);
/*     */     }
/*     */     
/* 290 */     if ((this.mOperation == Op.MOVE) || (this.mOperation == Op.SPAM) || (this.mOperation == Op.COPY) || (this.mOperation == Op.RENAME) || (this.mOperation == Op.UPDATE)) {
/* 291 */       toRet.append(" iidFolder=").append(this.mIidFolder);
/*     */     }
/*     */     
/* 294 */     if (this.mOperation == Op.UPDATE) {
/* 295 */       if (this.mFlags != null) {
/* 296 */         toRet.append(" flags=").append(this.mFlags);
/*     */       }
/* 298 */       if (this.mTags != null) {
/* 299 */         toRet.append(" tags=").append(com.zimbra.cs.mailbox.util.TagUtil.encodeTags(this.mTags));
/*     */       }
/*     */     }
/* 302 */     return toRet.toString();
/*     */   }
/*     */   
/*     */   public void setTagName(String tagName) {
/* 306 */     assert (this.mOperation == Op.TAG);
/* 307 */     this.mTagName = tagName;
/*     */   }
/*     */   
/*     */   public void setColor(Color color) {
/* 311 */     assert ((this.mOperation == Op.COLOR) || (this.mOperation == Op.UPDATE));
/* 312 */     this.mColor = color;
/*     */   }
/*     */   
/*     */   public void setName(String name) {
/* 316 */     assert ((this.mOperation == Op.RENAME) || (this.mOperation == Op.UPDATE));
/* 317 */     this.mName = name;
/*     */   }
/*     */   
/*     */   public void setIidFolder(ItemId iidFolder) {
/* 321 */     assert ((this.mOperation == Op.MOVE) || (this.mOperation == Op.SPAM) || (this.mOperation == Op.COPY) || (this.mOperation == Op.RENAME) || (this.mOperation == Op.UPDATE) || (this.mOperation == Op.RECOVER));
/* 322 */     this.mIidRequestedFolder = (this.mIidFolder = iidFolder);
/*     */   }
/*     */   
/*     */   public void setFlags(String flags) {
/* 326 */     assert (this.mOperation == Op.UPDATE);
/* 327 */     this.mFlags = flags;
/*     */   }
/*     */   
/*     */   public void setTags(String[] tags) {
/* 331 */     assert (this.mOperation == Op.UPDATE);
/* 332 */     this.mTags = tags;
/*     */   }
/*     */   
/*     */   ItemActionHelper(OperationContext octxt, Mailbox mbox, SoapProtocol responseProto, List<Integer> ids, Op op, MailItem.Type type, boolean flagValue, MailItem.TargetConstraint tcon)
/*     */     throws ServiceException
/*     */   {
/* 338 */     this.mOpCtxt = octxt;
/* 339 */     this.mMailbox = mbox;
/*     */     
/* 341 */     this.mAuthenticatedAccount = (octxt == null ? null : octxt.getAuthenticatedUser());
/* 342 */     if (this.mAuthenticatedAccount == null)
/* 343 */       this.mAuthenticatedAccount = mbox.getAccount();
/* 344 */     this.mIdFormatter = new ItemIdFormatter(this.mAuthenticatedAccount, mbox, false);
/* 345 */     this.mResponseProtocol = responseProto;
/*     */     
/* 347 */     int i = 0;
/* 348 */     this.itemIds = new int[ids.size()];
/* 349 */     for (Iterator i$ = ids.iterator(); i$.hasNext();) { int id = ((Integer)i$.next()).intValue();
/* 350 */       this.itemIds[(i++)] = id;
/*     */     }
/* 352 */     this.mOperation = op;
/* 353 */     if (this.mOperation == null)
/* 354 */       throw ServiceException.INVALID_REQUEST("unknown operation: null", null);
/* 355 */     this.type = type;
/* 356 */     this.mFlagValue = flagValue;
/* 357 */     this.mTargetConstraint = tcon;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/* 362 */   protected Mailbox getMailbox() { return this.mMailbox; }
/* 363 */   protected OperationContext getOpCtxt() { return this.mOpCtxt; }
/*     */   
/*     */   protected void schedule() throws ServiceException {
/* 366 */     boolean targeted = (this.mOperation == Op.MOVE) || (this.mOperation == Op.SPAM) || (this.mOperation == Op.COPY) || (this.mOperation == Op.RENAME) || (this.mOperation == Op.UPDATE);
/*     */     
/*     */ 
/* 369 */     if ((targeted) && (this.mIidFolder.belongsTo(this.mMailbox)) && (this.mIidFolder.getId() > 0) && (this.mIidFolder.getId() != 3) && (this.mIidFolder.getId() != 4)) {
/*     */       try {
/* 371 */         Folder folder = this.mMailbox.getFolderById(this.mOpCtxt, this.mIidFolder.getId());
/* 372 */         if (((folder instanceof Mountpoint)) && (!((Mountpoint)folder).getOwnerId().equals(this.mIidFolder.getAccountId()))) {
/* 373 */           this.mIidFolder = ((Mountpoint)folder).getTarget();
/* 374 */           this.mHopCount += 1;
/*     */         }
/*     */       }
/*     */       catch (ServiceException e) {}
/*     */     }
/*     */     
/*     */     try
/*     */     {
/* 382 */       if ((!targeted) || (this.mIidFolder.belongsTo(this.mMailbox))) {
/* 383 */         executeLocal();
/*     */       } else
/* 385 */         executeRemote();
/*     */     } catch (IOException ioe) {
/* 387 */       throw ServiceException.FAILURE("exception reading item blob", ioe);
/*     */     }
/*     */     
/* 390 */     StringBuilder successes = new StringBuilder();
/* 391 */     for (int id : this.itemIds)
/* 392 */       successes.append(successes.length() > 0 ? "," : "").append(this.mIdFormatter.formatItemId(id));
/* 393 */     this.mResult = successes.toString();
/*     */   }
/*     */   
/*     */   public String getResult() {
/* 397 */     return this.mResult;
/*     */   }
/*     */   
/*     */   public List<String> getCreatedIds() {
/* 401 */     return this.mCreatedIds;
/*     */   }
/*     */   
/*     */   private void executeLocalBatch(int[] ids) throws ServiceException
/*     */   {
/* 406 */     switch (this.mOperation) {
/*     */     case FLAG: 
/* 408 */       getMailbox().alterTag(getOpCtxt(), ids, this.type, Flag.FlagInfo.FLAGGED, this.mFlagValue, this.mTargetConstraint);
/* 409 */       break;
/*     */     case PRIORITY: 
/* 411 */       getMailbox().alterTag(getOpCtxt(), ids, this.type, Flag.FlagInfo.PRIORITY, this.mFlagValue, this.mTargetConstraint);
/* 412 */       break;
/*     */     case READ: 
/* 414 */       getMailbox().alterTag(getOpCtxt(), ids, this.type, Flag.FlagInfo.UNREAD, !this.mFlagValue, this.mTargetConstraint);
/* 415 */       break;
/*     */     case TAG: 
/* 417 */       getMailbox().alterTag(getOpCtxt(), ids, this.type, this.mTagName, this.mFlagValue, this.mTargetConstraint);
/* 418 */       break;
/*     */     case COLOR: 
/* 420 */       getMailbox().setColor(getOpCtxt(), ids, this.type, this.mColor);
/* 421 */       break;
/*     */     case HARD_DELETE: 
/* 423 */       getMailbox().delete(getOpCtxt(), ids, this.type, this.mTargetConstraint);
/* 424 */       break;
/*     */     case RECOVER: 
/* 426 */       getMailbox().recover(getOpCtxt(), ids, this.type, this.mIidFolder.getId());
/* 427 */       break;
/*     */     case DUMPSTER_DELETE: 
/* 429 */       getMailbox().deleteFromDumpster(getOpCtxt(), ids);
/* 430 */       break;
/*     */     case SPAM: 
/*     */     case MOVE: 
/* 433 */       getMailbox().move(getOpCtxt(), ids, this.type, this.mIidFolder.getId(), this.mTargetConstraint);
/* 434 */       break;
/*     */     case COPY: 
/* 436 */       List<MailItem> copies = getMailbox().copy(getOpCtxt(), ids, this.type, this.mIidFolder.getId());
/* 437 */       this.mCreatedIds = new ArrayList(ids.length);
/* 438 */       for (MailItem item : copies) {
/* 439 */         this.mCreatedIds.add(this.mIdFormatter.formatItemId(item));
/*     */       }
/* 441 */       break;
/*     */     case RENAME: 
/* 443 */       for (int id : ids) {
/* 444 */         getMailbox().rename(getOpCtxt(), id, this.type, this.mName, this.mIidFolder.getId());
/*     */       }
/* 446 */       break;
/*     */     case UPDATE: 
/* 448 */       if (this.mName != null) {
/* 449 */         for (int id : ids) {
/* 450 */           getMailbox().rename(getOpCtxt(), id, this.type, this.mName, this.mIidFolder.getId());
/*     */         }
/* 452 */       } else if (this.mIidFolder.getId() > 0) {
/* 453 */         getMailbox().move(getOpCtxt(), ids, this.type, this.mIidFolder.getId(), this.mTargetConstraint);
/*     */       }
/* 455 */       if ((this.mTags != null) || (this.mFlags != null)) {
/* 456 */         int flagMask = Flag.toBitmask(this.mFlags);
/* 457 */         if (this.mFlags == null) {
/* 458 */           flagMask = Integer.MIN_VALUE;
/*     */         }
/*     */         
/* 461 */         if (this.mTags == null) {
/* 462 */           this.mTags = MailItem.TAG_UNCHANGED;
/*     */         }
/* 464 */         getMailbox().setTags(getOpCtxt(), ids, this.type, flagMask, this.mTags, this.mTargetConstraint);
/*     */       }
/* 466 */       if (this.mColor != null) {
/* 467 */         getMailbox().setColor(getOpCtxt(), ids, this.type, this.mColor);
/*     */       }
/*     */       break;
/*     */     case LOCK: 
/* 471 */       for (int id : ids) {
/* 472 */         getMailbox().lock(getOpCtxt(), id, this.type, this.mAuthenticatedAccount.getId());
/*     */       }
/* 474 */       break;
/*     */     case UNLOCK: 
/* 476 */       for (int id : ids) {
/* 477 */         getMailbox().unlock(getOpCtxt(), id, this.type, this.mAuthenticatedAccount.getId());
/*     */       }
/* 479 */       break;
/*     */     default: 
/* 481 */       throw ServiceException.INVALID_REQUEST("unknown operation: " + this.mOperation, null);
/*     */     }
/*     */   }
/*     */   
/*     */   private void executeLocal() throws ServiceException {
/* 486 */     int batchSize = Provisioning.getInstance().getLocalServer().getItemActionBatchSize();
/* 487 */     ZimbraLog.mailbox.debug("ItemAction batchSize=%d", new Object[] { Integer.valueOf(batchSize) });
/* 488 */     if (this.itemIds.length <= batchSize) {
/* 489 */       executeLocalBatch(this.itemIds);
/* 490 */       return;
/*     */     }
/* 492 */     int offset = 0;
/* 493 */     while (offset < this.itemIds.length) {
/* 494 */       int[] batchOfIds = Arrays.copyOfRange(this.itemIds, offset, offset + batchSize < this.itemIds.length ? offset + batchSize : this.itemIds.length);
/*     */       
/* 496 */       executeLocalBatch(batchOfIds);
/* 497 */       offset += batchSize;
/* 498 */       if (offset < this.itemIds.length) {
/* 499 */         Thread.yield();
/*     */       }
/*     */     }
/*     */   }
/*     */   
/*     */   private AuthToken getAuthToken() throws ServiceException {
/* 505 */     AuthToken authToken = null;
/*     */     
/* 507 */     if (this.mOpCtxt != null) {
/* 508 */       authToken = AuthToken.getCsrfUnsecuredAuthToken(this.mOpCtxt.getAuthToken());
/*     */     }
/* 510 */     if (authToken == null) {
/* 511 */       authToken = com.zimbra.cs.service.AuthProvider.getAuthToken(this.mAuthenticatedAccount);
/*     */     }
/* 513 */     return authToken;
/*     */   }
/*     */   
/*     */   private void executeRemote() throws ServiceException, IOException {
/* 517 */     Account target = Provisioning.getInstance().get(Key.AccountBy.id, this.mIidFolder.getAccountId());
/*     */     
/* 519 */     AuthToken at = getAuthToken();
/* 520 */     String pxyAuthToken = Provisioning.onLocalServer(target) ? null : at.getProxyAuthToken();
/* 521 */     ZAuthToken zat = null;
/* 522 */     if (pxyAuthToken == null) {
/* 523 */       zat = at.toZAuthToken();
/* 524 */       zat.resetProxyAuthToken();
/*     */     } else {
/* 526 */       zat = new ZAuthToken(pxyAuthToken);
/*     */     }
/*     */     
/* 529 */     ZMailbox.Options zoptions = new ZMailbox.Options(zat, com.zimbra.cs.util.AccountUtil.getSoapUri(target));
/* 530 */     zoptions.setNoSession(true);
/* 531 */     zoptions.setTargetAccount(target.getId());
/* 532 */     zoptions.setTargetAccountBy(Key.AccountBy.id);
/* 533 */     ZMailbox zmbx = ZMailbox.getMailbox(zoptions);
/*     */     
/*     */ 
/* 536 */     ZFolder zfolder = zmbx.getFolderById(this.mIidFolder.toString(this.mAuthenticatedAccount));
/* 537 */     if ((zfolder instanceof ZMountpoint)) {
/* 538 */       ItemId iidTarget = new ItemId(((ZMountpoint)zfolder).getCanonicalRemoteId(), this.mAuthenticatedAccount.getId());
/* 539 */       if (!this.mIidFolder.equals(iidTarget)) {
/* 540 */         this.mIidFolder = iidTarget;
/* 541 */         if (++this.mHopCount > 5)
/* 542 */           throw MailServiceException.TOO_MANY_HOPS(this.mIidRequestedFolder);
/* 543 */         schedule();
/* 544 */         return;
/*     */       }
/*     */     }
/*     */     
/* 548 */     boolean deleteOriginal = this.mOperation != Op.COPY;
/* 549 */     String folderStr = this.mIidFolder.toString();
/* 550 */     this.mCreatedIds = new ArrayList(this.itemIds.length);
/*     */     
/* 552 */     boolean toSpam = this.mIidFolder.getId() == 4;
/* 553 */     boolean toMailbox = (!toSpam) && (this.mIidFolder.getId() != 3);
/*     */     
/* 555 */     for (MailItem item : this.mMailbox.getItemById(this.mOpCtxt, this.itemIds, this.type)) {
/* 556 */       if (item != null)
/*     */       {
/*     */ 
/* 559 */         List<Message> msgs = null;
/* 560 */         if ((item instanceof Conversation)) {
/* 561 */           msgs = this.mMailbox.getMessagesByConversation(this.mOpCtxt, item.getId(), com.zimbra.cs.index.SortBy.DATE_ASC, -1);
/*     */         }
/* 563 */         if (deleteOriginal) {
/* 564 */           if (msgs != null)
/*     */           {
/* 566 */             boolean permDenied = false;
/* 567 */             for (Iterator<Message> it = msgs.iterator(); it.hasNext();) {
/* 568 */               Message msg = (Message)it.next();
/* 569 */               if (!MailItem.TargetConstraint.checkItem(this.mTargetConstraint, msg)) {
/* 570 */                 it.remove();
/* 571 */               } else if (!canDelete(msg)) {
/* 572 */                 it.remove();permDenied = true;
/*     */               }
/*     */             }
/*     */             
/* 576 */             if (msgs.isEmpty()) {
/* 577 */               if (!permDenied) continue;
/* 578 */               throw ServiceException.PERM_DENIED("cannot delete any messages in " + item.getType() + " " + item.getId());
/*     */ 
/*     */             }
/*     */             
/*     */ 
/*     */ 
/*     */           }
/* 585 */           else if (!canDelete(item)) {
/* 586 */             throw ServiceException.PERM_DENIED("cannot delete existing copy of " + item.getType() + " " + item.getId());
/*     */           }
/*     */         }
/*     */         
/*     */ 
/*     */ 
/* 592 */         boolean fromSpam = item.inSpam();
/* 593 */         if (((fromSpam) && (toMailbox)) || ((!fromSpam) && (toSpam))) {
/*     */           try {
/* 595 */             Folder dest = this.mMailbox.getFolderById(this.mOpCtxt, this.mIidFolder.getId());
/* 596 */             SpamHandler.SpamReport report = new SpamHandler.SpamReport(toSpam, "remote " + this.mOperation, dest.getPath());
/* 597 */             Folder source = this.mMailbox.getFolderById(this.mOpCtxt, item.getFolderId());
/* 598 */             report.setSourceFolderPath(source.getPath());
/* 599 */             report.setDestAccountName(target.getName());
/* 600 */             SpamHandler.getInstance().handle(this.mOpCtxt, this.mMailbox, item.getId(), item.getType(), report);
/*     */           } catch (OutOfMemoryError e) {
/* 602 */             com.zimbra.cs.util.Zimbra.halt("out of memory", e);
/*     */           } catch (Throwable t) {
/* 604 */             ZimbraLog.mailop.info("could not train spam filter: " + new ItemId(item).toString(), t);
/*     */           }
/*     */         }
/*     */         
/*     */ 
/* 609 */         String flags = (this.mOperation == Op.UPDATE) && (this.mFlags != null) ? this.mFlags : item.getFlagString();
/* 610 */         String name = ((this.mOperation == Op.RENAME) || (this.mOperation == Op.UPDATE)) && (this.mName != null) ? this.mName : item.getName();
/* 611 */         String createdId = null;
/* 612 */         InputStream in = null;
/*     */         
/* 614 */         switch (item.getType()) {
/*     */         case CONTACT: 
/* 616 */           Contact ct = (Contact)item;
/* 617 */           Map<String, ZMailbox.ZAttachmentInfo> attachments = new HashMap();
/* 618 */           for (Contact.Attachment att : ct.getAttachments()) {
/* 619 */             String attachmentId = zmbx.uploadAttachment(att.getFilename(), att.getContent(), att.getContentType(), 0);
/* 620 */             ZMailbox.ZAttachmentInfo info = new ZMailbox.ZAttachmentInfo().setAttachmentId(attachmentId);
/* 621 */             attachments.put(att.getName(), info);
/*     */           }
/* 623 */           Map<String, String> fields = ct.getFields();
/* 624 */           Map<String, String> members = new HashMap();
/* 625 */           for (String key : fields.keySet()) {
/* 626 */             if (ContactConstants.A_groupMember.equals(key)) {
/* 627 */               String memberEncoded = (String)fields.get(key);
/* 628 */               ContactGroup group = ContactGroup.init(memberEncoded);
/* 629 */               for (ContactGroup.Member m : group.getMembers()) {
/* 630 */                 members.put(m.getValue(), m.getType().getSoapEncoded());
/*     */               }
/* 632 */               break;
/*     */             }
/*     */           }
/* 635 */           fields.remove(ContactConstants.A_groupMember);
/* 636 */           ZContact contact = zmbx.createContact(folderStr, null, fields, attachments, members);
/* 637 */           createdId = contact.getId();
/* 638 */           this.mCreatedIds.add(createdId);
/* 639 */           break;
/*     */         case MESSAGE: 
/*     */           try {
/* 642 */             in = StoreManager.getInstance().getContent(item.getBlob());
/* 643 */             createdId = zmbx.addMessage(folderStr, flags, null, item.getDate(), in, item.getSize(), true);
/*     */           } finally {
/* 645 */             ByteUtil.closeStream(in);
/*     */           }
/* 647 */           this.mCreatedIds.add(createdId);
/* 648 */           break;
/*     */         case VIRTUAL_CONVERSATION: 
/*     */         case CONVERSATION: 
/* 651 */           for (Message msg : msgs) {
/* 652 */             flags = (this.mOperation == Op.UPDATE) && (this.mFlags != null) ? this.mFlags : msg.getFlagString();
/*     */             try {
/* 654 */               in = StoreManager.getInstance().getContent(msg.getBlob());
/* 655 */               createdId = zmbx.addMessage(folderStr, flags, null, msg.getDate(), in, msg.getSize(), true);
/*     */             } finally {
/* 657 */               ByteUtil.closeStream(in);
/*     */             }
/* 659 */             this.mCreatedIds.add(createdId);
/*     */           }
/* 661 */           break;
/*     */         case DOCUMENT: 
/* 663 */           Document doc = (Document)item;
/* 664 */           SoapHttpTransport transport = new SoapHttpTransport(zoptions.getUri());
/*     */           try {
/* 666 */             in = StoreManager.getInstance().getContent(doc.getBlob());
/* 667 */             String uploadId = zmbx.uploadContentAsStream(name, in, doc.getContentType(), doc.getSize(), 4000, true);
/*     */             
/*     */ 
/*     */ 
/*     */ 
/* 672 */             Element req = new Element.XMLElement(MailConstants.SAVE_DOCUMENT_REQUEST);
/* 673 */             Element edoc = req.addUniqueElement("doc");
/* 674 */             edoc.addAttribute("name", name);
/* 675 */             edoc.addAttribute("l", folderStr);
/* 676 */             edoc.addAttribute("f", flags);
/* 677 */             Element upload = edoc.addElement("upload");
/* 678 */             upload.addAttribute("id", uploadId);
/* 679 */             transport.setResponseProtocol(this.mResponseProtocol);
/* 680 */             transport.setAuthToken(zat);
/* 681 */             Element response = transport.invoke(req);
/* 682 */             createdId = response.getElement("doc").getAttribute("id");
/*     */           } finally {
/* 684 */             ByteUtil.closeStream(in);
/* 685 */             transport.shutdown();
/*     */           }
/* 687 */           this.mCreatedIds.add(createdId);
/* 688 */           break;
/*     */         case APPOINTMENT: 
/*     */         case TASK: 
/* 691 */           CalendarItem cal = (CalendarItem)item;
/*     */           
/* 693 */           if (!cal.isPublic()) {
/* 694 */             boolean asAdmin = this.mOpCtxt != null ? this.mOpCtxt.isUsingAdminPrivileges() : false;
/* 695 */             if (!cal.allowPrivateAccess(this.mAuthenticatedAccount, asAdmin)) {
/* 696 */               throw ServiceException.PERM_DENIED("you do not have permission to move/copy a private calendar item from the current folder/mailbox");
/*     */             }
/*     */           }
/*     */           
/*     */ 
/* 701 */           QName qname = item.getType() == MailItem.Type.TASK ? MailConstants.SET_TASK_REQUEST : MailConstants.SET_APPOINTMENT_REQUEST;
/* 702 */           Element request = new Element.XMLElement(qname).addAttribute("l", folderStr).addAttribute("f", flags);
/* 703 */           ToXML.encodeAlarmTimes(request, cal);
/*     */           
/* 705 */           Invite invDefault = cal.getDefaultInviteOrNull();
/*     */           
/*     */ 
/*     */ 
/* 709 */           boolean takeoverAsOrganizer = false;
/* 710 */           boolean blockMove = false;
/* 711 */           if (Op.MOVE.equals(this.mOperation)) {
/* 712 */             Invite inv = invDefault;
/* 713 */             if (inv == null)
/*     */             {
/* 715 */               Invite[] invs = cal.getInvites();
/* 716 */               if ((invs != null) && (invs.length > 0))
/* 717 */                 inv = invs[0];
/*     */             }
/* 719 */             takeoverAsOrganizer = (inv != null) && (inv.isOrganizer());
/* 720 */             blockMove = (takeoverAsOrganizer) && (inv.hasOtherAttendees());
/*     */           }
/*     */           
/* 723 */           if (blockMove) {
/* 724 */             throw MailServiceException.INVALID_REQUEST("This operation requires change of organizer and it is not permitted", null);
/*     */           }
/*     */           
/*     */ 
/* 728 */           if (invDefault != null) {
/* 729 */             addCalendarPart(request.addUniqueElement("default"), cal, invDefault, zmbx, target, takeoverAsOrganizer);
/*     */           }
/*     */           
/* 732 */           for (Invite inv : cal.getInvites()) {
/* 733 */             if ((inv != null) && (inv != invDefault))
/*     */             {
/* 735 */               String elem = inv.isCancel() ? "cancel" : "except";
/* 736 */               addCalendarPart(request.addElement(elem), cal, inv, zmbx, target, takeoverAsOrganizer);
/*     */             }
/*     */           }
/* 739 */           ToXML.encodeCalendarReplies(request, cal);
/*     */           
/* 741 */           createdId = zmbx.invoke(request).getAttribute("calItemId");
/* 742 */           this.mCreatedIds.add(createdId);
/* 743 */           break;
/*     */         default: 
/* 745 */           throw MailServiceException.CANNOT_COPY(item.getId());
/*     */         }
/*     */         try
/*     */         {
/* 749 */           if ((deleteOriginal) && (!this.mIdFormatter.formatItemId(item).equals(createdId))) {
/* 750 */             if (msgs == null) {
/* 751 */               this.mMailbox.delete(this.mOpCtxt, item.getId(), item.getType());
/*     */             } else {
/* 753 */               for (Message msg : msgs)
/* 754 */                 this.mMailbox.delete(this.mOpCtxt, msg.getId(), msg.getType());
/*     */             }
/*     */           }
/*     */         } catch (ServiceException e) {
/* 758 */           if (e.getCode() != "service.PERM_DENIED") {
/* 759 */             throw e;
/*     */           }
/* 761 */           ZimbraLog.misc.info("could not delete original item " + item.getId() + "; treating operation as a copy instead");
/*     */         }
/*     */       }
/*     */     }
/*     */   }
/*     */   
/*     */   private void addCalendarPart(Element parent, CalendarItem cal, Invite inv, ZMailbox zmbx, Account target, boolean takeoverAsOrganizer) throws ServiceException {
/* 768 */     parent.addAttribute("ptst", inv.getPartStat());
/* 769 */     Element m = parent.addUniqueElement("m");
/*     */     
/* 771 */     Pair<MimeMessage, Integer> spinfo = cal.getSubpartMessageData(inv.getMailItemId());
/* 772 */     if (spinfo != null) {
/*     */       try {
/* 774 */         ByteArrayOutputStream baos = new ByteArrayOutputStream(((Integer)spinfo.getSecond()).intValue());
/* 775 */         ((MimeMessage)spinfo.getFirst()).writeTo(baos);
/* 776 */         String uploadId = zmbx.uploadAttachment("message", baos.toByteArray(), "message/rfc822", 6000);
/* 777 */         m.addAttribute("aid", uploadId);
/*     */       } catch (IOException ioe) {
/* 779 */         ZimbraLog.misc.info("could not read subpart message for part " + inv.getComponentNum() + " of item " + cal.getId(), ioe);
/*     */       } catch (MessagingException me) {
/* 781 */         ZimbraLog.misc.info("could not read subpart message for part " + inv.getComponentNum() + " of item " + cal.getId(), me);
/*     */       }
/*     */     }
/*     */     
/* 785 */     if ((takeoverAsOrganizer) && (inv.isOrganizer()) && (inv.hasOrganizer())) {
/* 786 */       Invite invCopy = inv.newCopy();
/* 787 */       invCopy.setInviteId(inv.getMailItemId());
/*     */       
/* 789 */       invCopy.setSeqNo(inv.getSeqNo() + 1);
/* 790 */       invCopy.setDtStamp(System.currentTimeMillis());
/* 791 */       ZOrganizer org = invCopy.getOrganizer();
/* 792 */       org.setAddress(target.getName());
/* 793 */       org.setCn(target.getDisplayName());
/* 794 */       Account authAcct = this.mOpCtxt != null ? this.mOpCtxt.getAuthenticatedUser() : target;
/* 795 */       if ((authAcct == null) || (authAcct.equals(target))) {
/* 796 */         org.setSentBy(null);
/*     */       } else
/* 798 */         org.setSentBy(authAcct.getName());
/* 799 */       inv = invCopy;
/*     */     }
/*     */     
/*     */ 
/* 803 */     ToXML.encodeInvite(m, this.mIdFormatter, getOpCtxt(), cal, inv, true);
/*     */   }
/*     */   
/*     */   private boolean canDelete(MailItem item) throws ServiceException {
/* 807 */     return (this.mMailbox.getEffectivePermissions(this.mOpCtxt, item.getId(), item.getType()) & 0x8) != 0;
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/service/mail/ItemActionHelper.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */